from django.contrib.contenttypes.models import ContentType
from django.contrib.auth import get_user_model
from rest_framework.serializers import (
    CharField,
    EmailField,
    HyperlinkedIdentityField,
    ModelSerializer,
    SerializerMethodField,
    ValidationError
    )
from accounts import models
import time, datetime, re, hashlib, random

Token = models.Token
User = models.User


class TokenCreateSerializer(ModelSerializer):
    class Meta:
        model = Token
        fields = [
            'token',
            'refresh_token',
            'expire_time',
        ]


class UserDetailSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = [
            'username',
            'college',
            'qq',
        ]


class UserCreateSerializer(ModelSerializer):
    class Meta:
        model = User
        fields = [
            'email',
            'username',
            'password',
            'college',
            'school',
            'qq',
            'user_token'
        ]
        extra_kwargs = {"password": {"write_only": True},
                        "user_token": {"read_only": True}}

    def validate(self, data):
        # email = data['email']
        # user_qs = User.objects.filter(email=email)
        # if user_qs.exists():
        #     raise ValidationError("This user has already registered.")
        return data

    def validate_password(self, value):
        data = self.get_initial()
        password = value
        if not re.match('^.{5,48}$', password):
            raise ValidationError("Invalid password")
        return value

    def validate_email(self, value):
        data = self.get_initial()
        email = value
        user_qs = User.objects.filter(email=email)
        if user_qs.exists():
            raise ValidationError("This user has already registered.")
        return value

    def validate_qq(self, value):
        data = self.get_initial()
        qq = value
        if not re.match('^[0-9]{5,15}$', qq):
            raise ValidationError("Invalid qq number")
        return value

    def create(self, validated_data):
        email = validated_data['email']
        username = validated_data['username']
        password = validated_data['password']
        college = validated_data['college']
        school = validated_data['school']
        qq = validated_data['qq']

        random.seed(time.time())
        random_num = random.uniform(0, 1)
        token = hashlib.sha1('%.3f' % ((random_num * time.time())**0.5 % 17)).hexdigest()
        re_token = hashlib.sha1('%.3f' % ((random_num * time.time())**0.4 % 7)).hexdigest()

        expire_time = datetime.datetime.now()+datetime.timedelta(seconds=72000)

        new_token = models.Token(token=token, refresh_token=re_token, expire_time=expire_time)
        new_token.save()

        user_obj = User(
            email=email,
            username=username,
            college=college,
            school=school,
            qq=qq,
        )
        user_obj.set_password(password)
        user_obj.set_token(new_token)
        user_obj.save()

        token_serializer = TokenCreateSerializer(new_token)
        print(user_obj.user_token.token)
        return user_obj


class UserLoginSerializer(ModelSerializer):

    email = EmailField(label='Email Address')
    # token = CharField(allow_blank=True, read_only=True)

    class Meta:
        model = User
        fields = [
            'email',
            'password',
        ]
        extra_kwargs = {"password": {"write_only": True}}

    def validate(self, data):
        data = self.get_initial()
        email = data.get("email")
        password = data.get("password")
        user_qs = User.objects.filter(email=email)
        if not user_qs.exists() and user_qs.count() != 1:
            raise ValidationError("This user does not exist")
        if not user_qs.filter(password=password):
            raise ValidationError("Incorrect password")
        return data
